﻿using Spk.Controls.Trees;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Spk.Controls.Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
            cbDrawMode.SelectedIndex = 0;
        }

        private void cbDrawMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (cbDrawMode.SelectedIndex)
            {
                case 0:
                    {
                        vtvTree.DrawMode = DrawModes.Default;
                        break;
                    }
                case 1:
                    {
                        vtvTree.DrawMode = DrawModes.OwnerDrawItemContents;
                        break;
                    }
                case 2:
                    {
                        vtvTree.DrawMode = DrawModes.OwnerDrawItems;
                        break;
                    }
                case 3:
                    {
                        vtvTree.DrawMode = DrawModes.System;
                        break;
                    }
                default:
                    throw new InvalidOperationException("Unsupported draw mode!");
            }

            tbNodeHeight.Enabled = (cbDrawMode.SelectedIndex != 0);
            bSetNodeHeight.Enabled = (cbDrawMode.SelectedIndex != 0);
        }

        private void bSetRootNodeCount_Click(object sender, EventArgs e)
        {
            uint rootNodeCount;
            if (uint.TryParse(tbRootNodeCount.Text, out rootNodeCount))
                vtvTree.RootNodeCount = rootNodeCount;
            else
                MessageBox.Show("Invalid root node count!");
        }

        private void bToggleSelected_Click(object sender, EventArgs e)
        {
            if (vtvTree.SelectedCount > 0)
                foreach (VirtualNode node in vtvTree.SelectedNodes)
                    vtvTree.ToggleNode(node);
        }

        private void bSetChildCount_Click(object sender, EventArgs e)
        {
            uint newChildCount;
            if (uint.TryParse(tbChildCount.Text, out newChildCount))
            {
                if (vtvTree.SelectedNode != null)
                    vtvTree.Node.ChildCount[vtvTree.SelectedNode] = newChildCount;
            }
        }

        private void bDeleteNode_Click(object sender, EventArgs e)
        {
            while (vtvTree.SelectedCount > 0)
                vtvTree.DeleteNode(vtvTree.SelectedNodes.First());
        }

        private void bDeleteChildNodes_Click(object sender, EventArgs e)
        {
            if (vtvTree.SelectedNode != null)
                vtvTree.DeleteChildren(vtvTree.SelectedNode);
        }

        private void cbMultiselect_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.MultiSelect = cbMultiselect.Checked;

            bDeleteChildNodes.Enabled = !cbMultiselect.Checked;
            tbChildCount.Enabled = !cbMultiselect.Checked;
            bSetChildCount.Enabled = !cbMultiselect.Checked;
        }

        private void bScrollToFocused_Click(object sender, EventArgs e)
        {
            if (vtvTree.FocusedNode != null)
                vtvTree.ScrollToNode(vtvTree.FocusedNode);
        }

        private void cbShowLines_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.ShowLines = cbShowLines.Checked;
        }

        private void cbShowRootLines_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.ShowRootLines = cbShowRootLines.Checked;
        }

        private void cbShowExpandMarks_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.ShowExpandMarks = cbShowExpandMarks.Checked;
        }

        private void cbShowImages_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.ShowImages = cbShowImages.Checked;
        }

        private void bHideSelected_Click(object sender, EventArgs e)
        {
            List<VirtualNode> nodes = new List<VirtualNode>();
            foreach (VirtualNode node in vtvTree.SelectedNodes)
                nodes.Add(node);

            foreach (VirtualNode node in nodes)
            {
                vtvTree.Node.Visible[node] = false;
                lbHiddenNodes.Items.Add(node);
            }
        }

        private void bShowChosen_Click(object sender, EventArgs e)
        {
            if (lbHiddenNodes.SelectedItem is VirtualNode)
            {
                VirtualNode node = (VirtualNode)lbHiddenNodes.SelectedItem;
                if (node.IsValid)
                {
                    vtvTree.Node.Visible[node] = true;
                }

                lbHiddenNodes.Items.Remove(lbHiddenNodes.SelectedItem);
            }
        }

        private void bSetFontSize_Click(object sender, EventArgs e)
        {
            uint newSize;
            if (uint.TryParse(tbFontSize.Text, out newSize))
            {
                vtvTree.Font = new Font(vtvTree.Font.FontFamily, (float)newSize);
            }
        }

        private void vtvTree_DrawNodeContents(object sender, DrawNodeContentsEventArgs e)
        {
            if (e.Node.IsSelected)
                e.Graphics.FillRectangle(SystemBrushes.Highlight, e.ContentsRect.Left, e.ContentsRect.Top, e.ContentsRect.Width - 1, e.ContentsRect.Height - 1);

            e.Graphics.DrawRectangle(SystemPens.WindowText, e.ContentsRect.Left, e.ContentsRect.Top, e.ContentsRect.Width - 1, e.ContentsRect.Height - 1);
            var size = e.Graphics.MeasureString("OwnerDraw node contents", vtvTree.Font);

            Brush b;
            if (e.Node.IsSelected)
                b = SystemBrushes.WindowText;
            else
                b = SystemBrushes.HighlightText;

            e.Graphics.DrawString("OwnerDraw node contents",
                vtvTree.Font,
                SystemBrushes.WindowText,
                new Point(e.ContentsRect.Left + (int)(e.ContentsRect.Width - size.Width) / 2,
                    e.ContentsRect.Top + (int)(e.ContentsRect.Height - size.Height) / 2));
        }

        private void vtvTree_DrawNode(object sender, DrawNodeEventArgs e)
        {
            if (e.Node.IsSelected)
                e.Graphics.FillRectangle(SystemBrushes.Highlight, e.NodeRect.Left, e.NodeRect.Top, e.NodeRect.Width - 1, e.NodeRect.Height - 1);

            string s = "OwnerDraw node " + e.Node.Index.ToString();

            e.Graphics.DrawRectangle(SystemPens.WindowText, e.NodeRect.Left, e.NodeRect.Top, e.NodeRect.Width - 1, e.NodeRect.Height - 1);
            var size = e.Graphics.MeasureString(s, vtvTree.Font);

            Brush b;
            if (e.Node.IsSelected)
                b = SystemBrushes.WindowText;
            else
                b = SystemBrushes.HighlightText;
            
            e.Graphics.DrawString(s,
                vtvTree.Font,
                SystemBrushes.WindowText,
                new Point(e.NodeRect.Left + (int)(e.NodeRect.Width - size.Width) / 2,
                    e.NodeRect.Top + (int)(e.NodeRect.Height - size.Height) / 2));
        }

        private void vtvTree_GetImageIndex(object sender, GetImageIndexEventArgs e)
        {
            e.ImageIndex = (int)e.Node.Index % ilImages.Images.Count;
        }

        private void vtvTree_GetNodeHeight(object sender, GetNodeHeightEventArgs e)
        {
            e.Height = 32;
        }

        private void vtvTree_GetNodeInitialData(object sender, InitNodeEventArgs e)
        {
            e.HasChildren = true;
            e.Visible = true;
        }

        private void vtvTree_GetText(object sender, GetTextEventArgs e)
        {
            e.Text = e.Node.ToString() + " - Very long node text";
        }

        private void vtvTree_GetChildCount(object sender, GetChildCountEventArgs e)
        {
            uint childCount;
            if (uint.TryParse(tbChildCount.Text, out childCount))
                e.ChildCount = childCount;
            else
                e.ChildCount = 0;
        }

        private void bSetNodeHeight_Click(object sender, EventArgs e)
        {
            uint newHeight;
            if (uint.TryParse(tbNodeHeight.Text, out newHeight))
            {
                if (vtvTree.SelectedNode != null)
                {
                    vtvTree.Node.Height[vtvTree.SelectedNode] = newHeight;
                }
            }
        }

        private void vtvTree_SelectionChanged(object sender, EventArgs e)
        {
            lbSelection.Items.Clear();

            if (vtvTree.SelectedCount > 0)
                for (int i = 0; i < vtvTree.SelectedCount; i++)
                {
                    lbSelection.Items.Add(vtvTree.SelectedNodes.ElementAt(i));
                }
        }

        private void vtvTree_GetNodeWidth(object sender, GetNodeWidthEventArgs e)
        {
            string s = "OwnerDraw node " + e.Node.Index.ToString();
            e.Width = (uint)(e.Graphics.MeasureString(s, vtvTree.Font).Width) + 40;
        }

        private void vtvTree_GetNodeContentsWidth(object sender, GetNodeContentsWidthEventArgs e)
        {
            e.Width = (uint)(e.Graphics.MeasureString("OwnerDraw node contents", vtvTree.Font).Width) + 40;
        }

        private void cbShowCheckboxes_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.ShowCheckboxes = cbShowCheckboxes.Checked;
        }

        private void cbAllowExpandCollapse_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.AllowExpandCollapse = cbAllowExpandCollapse.Checked;
        }

        private void cbHotTrack_CheckedChanged(object sender, EventArgs e)
        {
            vtvTree.HotTrack = cbHotTrack.Checked;
        }

        private void vtvTree_CheckedNodesChanged(object sender, EventArgs e)
        {
            lbCheckedNodes.Items.Clear();

            for (int i = 0; i < vtvTree.CheckedNodes.Count; i++)
            {
                lbCheckedNodes.Items.Add(vtvTree.CheckedNodes.ElementAt(i));
            }
        }

        private void bInsertBefore_Click(object sender, EventArgs e)
        {
            if (vtvTree.SelectedNode != null)
                vtvTree.InsertNodeBefore(vtvTree.SelectedNode);
        }

        private void bInsertAfter_Click(object sender, EventArgs e)
        {
            if (vtvTree.SelectedNode != null)
                vtvTree.InsertNodeAfter(vtvTree.SelectedNode);
        }

        private void bAddChild_Click(object sender, EventArgs e)
        {
            if (vtvTree.SelectedNode != null)
                vtvTree.AddChildNode(vtvTree.SelectedNode);
        }
    }
}
